package jwdt.xadmin.flow.action;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jwdt.xadmin.flow.SnakerHelper;
import jwdt.xadmin.system.bean.TUser;

import org.snaker.engine.access.Pager;
import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.entity.HistoryOrder;
import org.snaker.engine.entity.HistoryTask;
import org.snaker.engine.entity.Process;
import org.snaker.engine.entity.Task;
import org.snaker.engine.helper.AssertHelper;
import org.snaker.engine.helper.StreamHelper;
import org.snaker.engine.helper.StringHelper;
import org.snaker.engine.model.ProcessModel;

import com.ezerg.util.JsonUtil;
import com.ezerg.util.StringUtil;
import com.ezerg.web.Form;
import com.ezerg.web.Module;
import com.ezerg.web.Page;
import com.ezerg.web.annotation.Controller;
import com.ezerg.web.annotation.RequestMapping;
import com.ezerg.web.fileupload.FileItem;

/**
 * 流程定义
 */
@Controller("/xadmin/flow")
public class ProcessAction extends SnakerAction {
	
	/**
	 * 流程定义查询列表
	 */
	@RequestMapping("/processList")
	public Page doProcessList(Form f, Module m) {
		QueryFilter filter = new QueryFilter();
		String displayName = f.getString("displayName");
		if(StringHelper.isNotEmpty(displayName)) {
			filter.setDisplayName(displayName);
		}
		filter.setOrderBy("create_Time");
		filter.setOrder("DESC");
		Pager<Process> page = new Pager<Process>();
		page.setPageNo(f.getInt("pageNo", 1));
		engine.process().getProcesss(page, filter);
		f.add("page", page);
		return m.getJspPage(url +"processList.jsp");
	}
	
	/**
	 * 初始化流程定义
	 */
	@RequestMapping("/processInit")
	public Page doInit(Form f, Module m) {
		initFlows();
		return m.getRedirectPage(url+"processList.do");
	}
	
	/**
	 * 根据流程定义部署
	 */
	@RequestMapping("/processDeploy")
	public Page doDeploy(Form f, Module m) {
		return m.getJspPage(url+"processDeploy.jsp");
	}
	
	/**
	 * 新建流程定义
	 */
	@RequestMapping("/processAdd")
	public Page doAdd(Form f, Module m) {
		return m.getJspPage(url+"processAdd.jsp");
	}
	
	/**
	 * 新建流程定义[web流程设计器]
	 */
	@RequestMapping("/processDesigner")
	public Page doDesigner(Form f, Module m) {
		String processId = f.getString(PARA_PROCESSID);
		if(!StringUtil.nullOrBlank(processId)) {
			Process process = engine.process().getProcessById(processId);
			AssertHelper.notNull(process);
			ProcessModel processModel = process.getModel();
			if(processModel != null) {
				String json = SnakerHelper.getModelJson(processModel);
				f.add("process", json);
			}
			f.add("processId", processId);
		}
		return m.jspPage(url.concat("processDesigner.jsp"));
	}
	
	/**
	 * 编辑流程定义
	 */
	@RequestMapping("/processEdit")
	public Page doEdit(Form f, Module m) {
		String processId = f.getString(PARA_PROCESSID);
		Process process = engine.process().getProcessById(processId);
		f.add("process", process);
		if(process.getDBContent() != null) {
            try {
            	f.add("content", StringHelper.textXML(new String(process.getDBContent(), "UTF-8")));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
		return m.jspPage(url.concat("processEdit.jsp"));
	}
	
	/**
	 * 根据流程定义ID，删除流程定义
	 */
	@RequestMapping("/processDelete")
	public Page doDelete(Form f, Module m) {
		String processId = f.getString(PARA_PROCESSID);
		engine.process().undeploy(processId);
		return m.redirectPage(url.concat("processList.do"));
	}
	
	/**
	 * 添加流程定义后的部署
	 */
	@RequestMapping("/processFileDeploy")
	public Page doFileDeploy(Form f, Module m) {
		InputStream input = null;
		try {
			String id = f.getString("id");
			FileItem file = f.getFileItem("snakerFile");
			input = file.getInputStream();
			if(input.available()>0){
				if(!StringUtil.nullOrBlank(id)) {
					engine.process().redeploy(id, input);
				} else {
					engine.process().deploy(input);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(input != null) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return m.redirectPage(url.concat("processList.do"));
	}
	
	/**
	 * 保存流程定义[web流程设计器]
	 * @param model
	 * @return
	 */
	@RequestMapping("/processStringDeploy")
	public Page doStringDeploy(Form f, Module m) {
		InputStream input = null;
		try {
			String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" + SnakerHelper.convertXml(f.getString("model"));
			String id = f.getString("id");
			input = StreamHelper.getStreamFromString(xml);
			if(!StringUtil.nullOrBlank(id)) {
				engine.process().redeploy(id, input);
			} else {
				engine.process().deploy(input);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return m.writePage(f, "false");
		} finally {
			if(input != null) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return m.writePage(f, "true");
	}
	
	/**
	 * 通用的流程启动
	 */
	@RequestMapping("processStart")
	public Page doProcessStart(Form f, Module m) {
		TUser user = (TUser) f.getSession("userInfo");
		startInstanceByName(f.getString("processName"), null, user.getUsername(), null);
		return m.getRedirectPage(url+"processList.do");
	}
	
	/**
	 * 流程图展现需要的json数据
	 */
	@RequestMapping("/processJson")
	public Page doJson(Form f, Module m) {
		String processId = f.getString(PARA_PROCESSID);
		String orderId = f.getString(PARA_ORDERID);
		List<Task> tasks = null;
		if(!StringUtil.nullOrBlank(orderId)) {
			tasks = engine.query().getActiveTasks(new QueryFilter().setOrderId(orderId));
		}
		Process process = engine.process().getProcessById(processId);
		AssertHelper.notNull(process);
		ProcessModel model = process.getModel();
		Map<String, String> jsonMap = new HashMap<String, String>();
		if(model != null) {
			jsonMap.put("process", SnakerHelper.getModelJson(model));
		}		
		//{"activeRects":{"rects":[{"paths":[],"name":"任务3"},{"paths":[],"name":"任务4"},{"paths":[],"name":"任务2"}]},"historyRects":{"rects":[{"paths":["TO 任务1"],"name":"开始"},{"paths":["TO 分支"],"name":"任务1"},{"paths":["TO 任务3","TO 任务4","TO 任务2"],"name":"分支"}]}}
		if(tasks != null && !tasks.isEmpty()) {
			jsonMap.put("active", SnakerHelper.getActiveJson(tasks));
		}
		return m.writePage(f, JsonUtil.toJson(jsonMap));
	}
	
	/**
	 * 显示流程图与历史任务记录
	 */
	@RequestMapping("/processDisplay")
	public Page doDisplay(Form f, Module m) {
		String orderId = f.getString(PARA_ORDERID);
		HistoryOrder order = engine.query().getHistOrder(orderId);
		f.add("order", order);
		List<HistoryTask> tasks = engine.query().getHistoryTasks(new QueryFilter().setOrderId(orderId));
		f.add("tasks", tasks);
		return m.jspPage(url.concat("processView.jsp"));
	}
	
	/**
	 * 显示独立的流程图
	 */
	@RequestMapping("/processDiagram")
	public Page doDiagram(Form f, Module m) {
		return m.jspPage(url.concat("diagram.jsp"));
	}
}
